package agents

import (
	"encoding/json"
	"fmt"
	"time"
	"webhook-agents/config"
	"webhook-agents/utils"
)

// FalcoAlert represents the alert format from Falco
type FalcoAlert struct {
	Output       string                 `json:"output"`
	Priority     string                 `json:"priority"`
	Rule         string                 `json:"rule"`
	Time         string                 `json:"time"`
	OutputFields map[string]interface{} `json:"output_fields"`
	// 添加数据源标识字段
	DataSource string `json:"data_source,omitempty"`
}

// FalcoProcessor Falco处理器
type FalcoProcessor struct {
	httpClient *utils.HTTPClient
	ditingURL  string
	endpoint   string
}

// NewFalcoProcessor 创建新的Falco处理器
func NewFalcoProcessor() *FalcoProcessor {
	// 获取Falco端点配置
	endpointConfig, ok := config.Global.Diting.Endpoints["falco"]
	if !ok {
		// 如果配置不存在，使用默认值
		endpointConfig = config.EndpointConfig{
			Path:    "/alert/falco",
			Enabled: true,
		}
	}

	return &FalcoProcessor{
		httpClient: utils.NewHTTPClient(30 * time.Second),
		ditingURL:  config.Global.Diting.URL,
		endpoint:   endpointConfig.Path,
	}
}

// GetPriorityValue 获取优先级数值，数值越小优先级越高
func (f *FalcoProcessor) GetPriorityValue(priority string) int {
	// 定义优先级顺序，数字越小优先级越高
	priorityOrder := map[string]int{
		"Emergency":     1,
		"Alert":         2,
		"Critical":      3,
		"Error":         4,
		"Warning":       5,
		"Notice":        6,
		"Informational": 7,
		"Debug":         8,
	}

	if priorityValue, ok := priorityOrder[priority]; ok {
		return priorityValue
	}

	// 如果优先级不在列表中，默认返回最低优先级
	return 9
}

// IsPriorityHigherThan 检查优先级是否高于指定优先级
func (f *FalcoProcessor) IsPriorityHigherThan(priority string, minPriority string) bool {
	priorityValue := f.GetPriorityValue(priority)
	minPriorityValue := f.GetPriorityValue(minPriority)

	// 优先级数值越小优先级越高
	return priorityValue <= minPriorityValue
}

// IsRuleExcluded 检查规则是否在排除列表中
func (f *FalcoProcessor) IsRuleExcluded(rule string) bool {
	for _, excludedRule := range config.Global.Diting.FalcoFilter.ExcludeRules {
		if rule == excludedRule {
			return true
		}
	}
	return false
}

// ProcessAlert 处理Falco告警并发送到谛听系统
func (f *FalcoProcessor) ProcessAlert(alert interface{}) error {
	falcoAlert, ok := alert.(FalcoAlert)
	if !ok {
		return fmt.Errorf("无效的告警类型")
	}

	// 检查是否需要排除此规则
	if f.IsRuleExcluded(falcoAlert.Rule) {
		fmt.Printf("🚫 Falco告警规则已被排除: %s\n", falcoAlert.Rule)
		return nil
	}

	// 检查优先级是否满足最小优先级要求
	minPriority := config.Global.Diting.FalcoFilter.MinPriority
	if minPriority != "" {
		if !f.IsPriorityHigherThan(falcoAlert.Priority, minPriority) {
			fmt.Printf("ℹ️  Falco告警优先级低于配置的最小优先级，已过滤: %s (Priority: %s, 最小优先级: %s)\n",
				falcoAlert.Rule, falcoAlert.Priority, minPriority)
			return nil
		}
	} else {
		// 如果没有配置最小优先级，使用默认的Notice级别过滤
		if !f.IsPriorityHigherThan(falcoAlert.Priority, "Notice") {
			fmt.Printf("ℹ️  Falco告警优先级低于Notice，已过滤: %s (Priority: %s)\n",
				falcoAlert.Rule, falcoAlert.Priority)
			return nil
		}
	}

	// 添加数据源标识
	if falcoAlert.DataSource == "" {
		falcoAlert.DataSource = "falco"
	}

	// 确保OutputFields存在
	if falcoAlert.OutputFields == nil {
		falcoAlert.OutputFields = make(map[string]interface{})
	}

	// 构建完整URL
	url := fmt.Sprintf("%s%s", f.ditingURL, f.endpoint)

	// 提取需要的字段信息
	output := falcoAlert.Output
	rule := falcoAlert.Rule
	time := falcoAlert.Time

	// 从OutputFields中提取k8s信息
	var k8sNsName, k8sPodName string
	if falcoAlert.OutputFields != nil {
		if ns, ok := falcoAlert.OutputFields["k8s.ns.name"]; ok {
			if nsStr, ok := ns.(string); ok {
				k8sNsName = nsStr
			}
		}
		if pod, ok := falcoAlert.OutputFields["k8s.pod.name"]; ok {
			if podStr, ok := pod.(string); ok {
				k8sPodName = podStr
			}
		}
	}

	// 过滤OutputFields，只保留需要的字段
	filteredFields := make(map[string]interface{})
	if k8sNsName != "" {
		filteredFields["k8s.ns.name"] = k8sNsName
	}
	if k8sPodName != "" {
		filteredFields["k8s.pod.name"] = k8sPodName
	}
	// 添加数据源标识到OutputFields
	filteredFields["data_source"] = "falco"

	// 使用过滤后的字段
	falcoAlert.OutputFields = filteredFields

	// 打印过滤后的关键信息（接收的消息）
	fmt.Printf("🔔 接收到Falco告警:\n")
	fmt.Printf("   Rule: %s\n", rule)
	fmt.Printf("   Time: %s\n", time)
	fmt.Printf("   Priority: %s\n", falcoAlert.Priority)
	fmt.Printf("   Output: %s\n", output)
	if k8sNsName != "" {
		fmt.Printf("   Namespace: %s\n", k8sNsName)
	}
	if k8sPodName != "" {
		fmt.Printf("   Pod: %s\n", k8sPodName)
	}
	fmt.Println()

	// 打印将要发送到谛听系统的完整数据
	jsonData, err := json.MarshalIndent(falcoAlert, "", "  ")
	if err != nil {
		fmt.Printf("❌ 序列化发送数据失败: %v\n", err)
	} else {
		fmt.Printf("📤 准备发送到谛听系统的完整数据:\n%s\n", string(jsonData))
		fmt.Printf("   发送URL: %s\n", url)
	}
	fmt.Println()

	// 发送POST请求到谛听系统
	if err := f.httpClient.PostJSON(url, falcoAlert); err != nil {
		return fmt.Errorf("发送告警到谛听系统失败: %v", err)
	}

	fmt.Printf("✅ Falco告警已发送到谛听系统: %s (Rule: %s)\n", url, falcoAlert.Rule)
	return nil
}

// GetName 获取处理器名称
func (f *FalcoProcessor) GetName() string {
	return "FalcoProcessor"
}

// GetDescription 获取处理器描述
func (f *FalcoProcessor) GetDescription() string {
	return "处理Falco告警并转发到谛听系统"
}
